#!/usr/bin/env python3.10
# -*- encoding: utf-8 -*-
"""
@File    :   controllers.py
@Time    :   2024/02/19 15:59:37
@Author  :   windstarry 
@Version :   1.0
"""
# here put the import lib
from datetime import datetime

from django.contrib.auth import get_user_model, authenticate
from ninja_extra import api_controller, route
from django.shortcuts import get_object_or_404
from ninja_extra.permissions import IsAdminUser, IsAuthenticated
from ninja_jwt import schema
from ninja_jwt.authentication import JWTAuth
from ninja_extra.pagination import (
    PageNumberPaginationExtra,
    PaginatedResponseSchema,
    paginate,
)
from ninja_jwt.controller import TokenObtainSlidingController
from ninja_jwt.tokens import SlidingToken
from core.schemas import ErrorSchema
from .schema import (
    LoginSchema,
    UserInfoSchema,
    UserTokenOutSchema,
    RoleSchema,
    ClassSchema,
    CreatRoleSchema,
    CreateClassSchema,
)
from core.schemas import MessageSchema
from .models import Role,ClassModel

User = get_user_model()


@api_controller("/users", tags=["用户管理"], auth=JWTAuth())
class UserController:
    @route.get(
        "/info",
        summary="用户信息",
        url_name="user-info",
        response={201: UserInfoSchema},
        permissions=[IsAuthenticated],
    )
    def get_user_info(
        self,
    ):
        """
        获取用户信息
        :return: UserInfoSchema对象,包含用户信息
        """
        user_obj = self.context.request.user
        return user_obj


@api_controller("/users/role", tags=["角色管理"], auth=JWTAuth())
class UserRoleController:
    # 角色管理的路由
    @route.get(
        "",
        summary="角色列表",
        url_name="user-role-list",
        response=PaginatedResponseSchema[RoleSchema],
        permissions=[IsAuthenticated],
    )
    # 分页获取角色列表
    @paginate(PageNumberPaginationExtra, page_size=10)
    def get_user_role_list(
        self,
    ):
        """
        获取所有角色列表
        :return: 所有角色对象的查询结果
        """
        return Role.objects.all()

    @route.post(
        "",
        summary="新增角色",
        url_name="add-user-role",
        response=[(201, RoleSchema), (400, ErrorSchema)],
        permissions=[IsAdminUser],
    )
    def add_user_role(self, data: CreatRoleSchema):
        """
        新增角色
        :param data: CreatRoleSchema对象,包含新增角色所需的数据
        :return: RoleSchema对象
        """
        try:
            obj = data.create_obj(creator=self.context.request.user)
            return 201, obj
        except Exception as ex:
            return 400, {"message": "创建失败"}

    @route.get(
        "/{r_id}",
        summary="查询角色",
        url_name="user-role-info",
        response={201: RoleSchema},
        permissions=[IsAuthenticated],
    )
    def get_user_role_info(self, r_id: int):
        """
        查询角色信息
        :param r_id: 角色ID
        :return: RoleSchema对象
        """
        obj = get_object_or_404(Role, id=r_id)
        return obj

    @route.put(
        "/{r_id}",
        summary="更新角色",
        url_name="update-user-role",
        response=RoleSchema,
        permissions=[IsAdminUser],
    )
    def update_user_role(self, r_id: int, data: CreatRoleSchema):
        """
        更新角色信息
        :param r_id: 角色ID
        :param data: CreatRoleSchema对象,包含需要更新的角色信息
        :return: RoleSchema对象
        """
        obj = get_object_or_404(Role, id=r_id)
        obj.modifier = self.context.request.user.username
        data.update(obj)
        return obj

    @route.delete(
        "/{r_id}",
        summary="删除角色",
        response={200: MessageSchema},
        url_name="delete-user-role",
        permissions=[IsAdminUser],
    )
    def delete_user_role(self, r_id: int):
        """
        删除角色
        :param r_id: 角色ID
        :return:
        """
        obj = get_object_or_404(Role, id=r_id)
        obj.delete()
        return 200, {"message": "删除成功"}


@api_controller("/users/class", tags=["班级管理"], auth=JWTAuth())
class UserClassController:
    @route.get(
        "",
        summary="班级管理",
        url_name="user-class-list",
        response=PaginatedResponseSchema[ClassSchema],
        permissions=[IsAuthenticated],
    )
    @paginate(PageNumberPaginationExtra, page_size=10)
    def get_user_class_list(
        self,
    ):
        """
        获取班级信息
        :return: ClassSchema对象
        """
        return ClassModel.objects.all()
    
    @route.post(
        "",
        summary="新增班级",
        url_name="add-user-class",
        response=[(201, ClassSchema), (400, ErrorSchema)],
        permissions=[IsAdminUser],
    )
    def add_user_class(self, data: CreateClassSchema):
        """
        新增班级
        :param data: CreateClassSchema对象,包含新增班级所需的数据
        :return: ClassSchema对象
        """
        try:
            obj = data.create_obj(creator=self.context.request.user)
            return 201, obj
        except Exception as ex:
            return 400, {"message": "创建失败"}
        
    @route.get(
        "/{c_id}",
        summary="查询班级",
        url_name="user-class-info",
        response=ClassSchema,
        permissions=[IsAuthenticated],)
    def get_user_class_info(self, c_id: int):
        """
        查询班级信息
        :param c_id: 班级ID
        :return: ClassSchema对象
        """
        obj = get_object_or_404(ClassModel, id=c_id)
        return obj
    
    @route.put(
        "/{c_id}",
        summary="更新班级",
        url_name="update-user-class",
        response=ClassSchema,
        permissions=[IsAdminUser],)
    def update_user_class(self, c_id: int, data: CreateClassSchema):
        """
        更新班级信息
        :param c_id: 班级ID
        :param data: CreateClassSchema对象，包含需要更新的班级信息
        :return: ClassSchema对象
        """
        obj = get_object_or_404(ClassModel, id=c_id)
        obj.modifier = self.context.request.user.username
        data.update(obj)
        return obj
    
    @route.delete(
        "/{c_id}",
        summary="删除班级",
        response={200: MessageSchema},
        url_name="delete-user-class",
        permissions=[IsAdminUser],)
    def delete_user_class(self, c_id: int):
        """
        删除班级
        :param c_id: 班级ID
        :return:
        """
        obj = get_object_or_404(ClassModel, id=c_id)
        obj.delete()
        return 200, {"message": "删除成功"}
    

@api_controller("/auth", tags=["认证"])
class UserTokenController(TokenObtainSlidingController):
    @route.post("/login", response=UserTokenOutSchema, summary="登录", url_name="login")
    def obtain_token(self, auth: LoginSchema):
        """
        获取用户对象并生成令牌
        Args:
            auth (LoginSchema): 用户登录信息
        Returns:
            UserTokenOutSchema: 包含用户对象、令牌和过期时间的输出对象
        """
        # 获取用户对象
        user_obj = authenticate(username=auth.username, password=auth.password)
        # 生成令牌
        token = SlidingToken.for_user(user_obj)
        return UserTokenOutSchema(
            user=user_obj,
            token=str(token),
            token_exp_date=datetime.fromtimestamp(token["exp"]),
        )

    @route.post(
        "/api-token-refresh",
        response=schema.TokenRefreshSlidingSerializer,
        summary="刷新token",
        url_name="refresh",
    )
    def refresh_token(self, refresh_token: schema.TokenRefreshSlidingSchema):
        """
        刷新令牌
        参数:
            refresh_token (schema.TokenRefreshSlidingSchema): 用于刷新令牌的参数对象
        返回:
            refresh (schema.TokenRefreshSlidingSchema): 刷新后的令牌对象
        """
        refresh = schema.TokenRefreshSlidingSerializer(**refresh_token.dict())
        return refresh
